#ifndef GRIDCLIENT_H
#define GRIDCLIENT_H

/*!
 * \file GridClient.h
 * \author thomas raynal
 * \version 2.0
 */

#include <boost/asio.hpp>
#include "BehaviorHandler.h"
#include "GridPackedMessage.h"
#include "GridTcpConnection.h"

/*! \namespace Network
 * 
 * Group client/server related classes. Offer API for handling both server and clients.
 */
namespace Network
{

/*! \class GridClient
* \brief Represent a client.
* APIs for handling incoming message and write response on the opened socket
* Request & response message model must be specified
*/
template <class MessageRequest, class MessageResponse>
class GridClient 
{
public:

	 GridClient(boost::asio::io_service& io_service, tcp::endpoint& endpoint,BehaviorHandler<MessageRequest,MessageResponse>* h)
		 :service_ (io_service)
	 {
		 Create(endpoint,h);
		 
	 }


private:
	boost::shared_ptr<GridTcpConnection<MessageRequest,MessageResponse>> connection_;
	boost::asio::ip::tcp::endpoint endpoint_;
	boost::asio::io_service& service_;
	


	void Create(boost::asio::ip::tcp::endpoint& endpoint,BehaviorHandler<MessageRequest,MessageResponse>* handler)
	{
		connection_ = GridTcpConnection<MessageRequest,MessageResponse>::Create(service_,handler); //Create(service_);
		endpoint_ = endpoint;
		StartConnect ();
	}

	void StartConnect ()
	{
		connection_->GetSocket().async_connect(endpoint_,
		boost::bind(&GridClient::HandleConnect, this,
		connection_,
		boost::asio::placeholders::error)
		);
	}

	void HandleConnect(boost::shared_ptr<GridTcpConnection<MessageRequest,MessageResponse>> c, const boost::system::error_code& error)
	{
		if (!error)
		{
			c->Start();
		}
		else
		{
			cout << error.message();
		}
	}


};
}
#endif GRIDCLIENT_H